/******************************************************************************
 * Copyright (C) 2024 Createtree, Inc.(Gmbh) or its affiliates.
 *
 * All Rights Reserved.
 *
 * @file bsp_led_handler.h
 *
 * @par dependencies
 * - stdio.h
 * - stdint.h
 * - bsp_led_driver.h
 * @author Createtree | R&D Dept. | liuzhihuawy@163.com
 *
 * @brief Provide the APP APIs of LED and corresponding opetions.
 *
 * Processing flow:
 *
 * call directly.
 *
 * @version V1.0 2024-10-27
 *
 * @note 1 tab == 4 spaces!
 *
 *****************************************************************************/
#ifndef __BSP_LED_HANDLER_H__ // Avoid repeated including same files later
#define __BSP_LED_HANDLER_H__
//******************************** Includes *********************************//
#include <stdint.h>
#include <stdio.h>
#include "bsp_led_driver.h"
//******************************** Includes *********************************//

//******************************** Defines **********************************//
#define DEBUG                                   /* Debug mode                */
#define USING_LED_ASSERT                        /* Use parameter assert      */
#define OS_SUPPORTING                           /* OS is supported           */
#define MAX_LED_INSTANCE_NUM   BSP_ID_LED_MAX   /* Max LED instance number   */
                                                /* Handler instance pattern  */
#define HANDLER_INSTANCE_PATTERN ((bsp_led_driver_t*)0xA6A6A6A6)

typedef struct bsp_led_handler bsp_led_handler_t;

typedef enum
{
    BSP_ID_LED_1            = 0,  /* LED 1 index number whitch passed to app */
    BSP_ID_LED_2               ,  /* LED 2 index number whitch passed to app */
    BSP_ID_LED_3               ,  /* LED 3 index number whitch passed to app */
    BSP_ID_LED_4               ,  /* LED 4 index number whitch passed to app */
    BSP_ID_LED_5               ,  /* LED 5 index number whitch passed to app */
    BSP_ID_LED_6               ,  /* LED 6 index number whitch passed to app */
    BSP_ID_LED_7               ,  /* LED 7 index number whitch passed to app */
    BSP_ID_LED_8               ,  /* LED 8 index number whitch passed to app */
    BSP_ID_LED_9               ,  /* LED 9 index number whitch passed to app */
    BSP_ID_LED_MAX             ,  /* LED max number                          */
    BSP_ID_LED_NOT_INITIALIZED = 0xFF, /* LED not initialized ID             */
} led_id_t; /* LED Index */

typedef enum
{
    LED_HANDLER_STATUS_OK           =    0,  /* LED operation is successful  */
    LED_HANDLER_STATUS_ERROR        =    1,  /* LED operation is failed      */
    LED_HANDLER_STATUS_INITED       =    2,  /* LED is inited                */
    LED_HANDLER_STATUS_NOT_INITED   =    3,  /* LED is not inited            */
    LED_HANDLER_STATUS_REGISTERED   =    4,  /* LED is registered            */
    LED_HANDLER_STATUS_ERROR_RSRC   =    5,  /* LED resource error           */
    LED_HANDLER_STATUS_ERROR_PARAM  =    6,  /* LED parameter error          */
    LED_HANDLER_STATUS_TIMEOUT      =    8,  /* LED operation timeout        */
    LED_HANDLER_SATUS_RESERVED      = 0xFF,  /* Reserved                     */
} led_handler_status_t;

typedef enum
{
    LED_HANDLER_INITED       = 1,  /* LED is inited                          */
    LED_HANDLER_NOT_INITED   = 0,  /* LED is not inited                      */
} led_inited_state_t;

typedef struct
{
    led_handler_status_t (*pf_get_time)(uint32_t * const ms);
} handler_time_base_t;

#ifdef OS_SUPPORTING
typedef struct
{
    led_handler_status_t (*pf_sleep)(const uint32_t ms);
} handler_os_sleep_t;

typedef struct
{
    /* os queue create */
    led_handler_status_t (*pf_os_queue_create) (
                                                uint32_t const       cell_num,
                                                uint32_t const      cell_size,
                                                void **  const   queue_handle);

    /* os queue send */
    led_handler_status_t (*pf_os_queue_push)  (
                                               void  *   const   queue_handle,
                                               void  *   const            msg,
                                               uint32_t               timeout);

    /* os queue receive */
    led_handler_status_t (*pf_os_queue_pop)   (
                                               void  *   const   queue_handle,
                                               void  *   const            msg,
                                               uint32_t               timeout);

    /* os queue delete */
    led_handler_status_t (*pf_os_queue_delete)(void  *   const   queue_handle);

} handler_os_queue_op_t;

typedef struct
{
    /* entry critical section */
    void (*pf_os_critical_enter) (void);
    /* exit critical section */
    void (*pf_os_critical_exit)  (void);
    
} handler_os_critial_t;


typedef struct
{
    /* os thread create */
    led_handler_status_t (*pf_os_thread_create) (
                          void *   const       task_fn,     /* from internal */
                          const char        *task_name,     /* from external */
                          uint32_t const    stack_size,     /* from external */
                          void *   const    parameters,     /* from internal */
                          uint32_t const      priority,     /* from external */
                          void **  const   task_handle      /* from internal */
                          );
    /* os thread delete */
    led_handler_status_t (*pf_os_thread_delete) (
                          void *   const   task_handle);
} handler_os_thread_op_t;

#endif /* OS_SUPPORTING */

typedef led_handler_status_t (*pf_handler_led_ctrl_t) (
                             bsp_led_handler_t  * const    self,
                             const uint16_t              period,    /* ms    */
                             const uint8_t          blink_times,    /* times */
                             const led_duty_cycle_t  duty_cycle,
                             const led_id_t               led_id
                             );

typedef led_handler_status_t (*pf_led_register_t) (
                             bsp_led_handler_t * const      self,
                             bsp_led_driver_t  * const  hled_drv,
                             led_id_t          * const     led_id
                             );

typedef struct
{
    uint32_t num;
    bsp_led_driver_t * group[MAX_LED_INSTANCE_NUM];
} led_instance_registed_t;

struct bsp_led_handler
{
    /***************** Private variable ******************/
    /* internal status ----------------------------------*/
    uint8_t                                      is_inited;
    /* instances of registration */
    led_instance_registed_t                      instances;
    /* os object handle ---------------------------------*/
    void                                     *queue_handle;
    void                                    *thread_handle;

    /************* interfaces from external **************/
    /* from Core layer ----------------------------------*/
    const handler_time_base_t                 *p_time_base;
    /* from OS layer ------------------------------------*/
#ifdef OS_SUPPORTING
    const handler_os_sleep_t                   *p_os_sleep;
    const handler_os_queue_op_t             *p_os_queue_op;
    const handler_os_critial_t              *p_os_critical;
    const handler_os_thread_op_t           *p_os_thread_op;
#endif /* OS_SUPPORTING */
    /*********************** APIs ************************/
    /* For App ------------------------------------------*/
    pf_handler_led_ctrl_t                      pf_led_ctrl;
    /* For internal driver ------------------------------*/
    pf_led_register_t                      pf_led_register;
    
};

//******************************** Defines **********************************//

//******************************** Declaring ********************************//


/**
 * @brief led constructor function
 * @param self led handler instance
 * @param hled_op led operations instance
 * @param hos_sleep os sleep instance
 * @param htime_base time base instance
 * @retval led_handler_status_t status of the operation
 * @note This function is used to initialize the led handler
 *  steps:
 *  1. Check the input parameters
 *  2. Check if the led handler is already initialized
 *  3. Add the interfaces to the led handler instance
 *  4. Initialize the led handler
 * @date 2024-10-27
 */
led_handler_status_t led_handler_constructor(
                            bsp_led_handler_t        * const             self,
#ifdef OS_SUPPORTING
                      const handler_os_sleep_t       * const       p_os_sleep,
                      const handler_os_queue_op_t    * const    p_os_queue_op,
                      const handler_os_critial_t     * const    p_os_critical,
                      const handler_os_thread_op_t   * const   p_os_thread_op,
#endif /* OS_SUPPORTING */
                      const handler_time_base_t      * const      p_time_base);

//******************************** Declaring ********************************//

#endif /* __BSP_LED_HANDLER_H__ */
